
module State.IdUtils(IntegerId(..), insertAtNextId, insertAtNextIdM) where

import State.Database
import Prelude hiding (fromInteger, toInteger)
import Data.Map(Map)
import qualified Data.Map as Map
import Control.Monad.State.Lazy (State)
import Control.Monad.State.Class (MonadState(..))

-- | A class for integer object identifiers
class IntegerId id where
    toInteger :: id -> Integer
    fromInteger :: Integer -> id

instance IntegerId SubmissionId where
    toInteger (SubmissionId id) = id
    fromInteger id = SubmissionId id
instance IntegerId ProblemId where
    toInteger (ProblemId id) = id
    fromInteger id = ProblemId id

-- | Inserts an object into the map assigning it a new ID. Should probably return the ID assigned, but does not.
insertAtNextId :: (Ord k, IntegerId k) => v -> Map k v -> Map k v
insertAtNextId item map = Map.insert (fromInteger $ maybe 0 ((+1).toInteger.fst.fst) (Map.maxViewWithKey map)) item map

insertAtNextIdM :: (Ord k, IntegerId k) => v -> State (Map k v) k
insertAtNextIdM item = do
    map <- get
    let newKey = (fromInteger $ maybe 0 ((+1).toInteger.fst.fst) (Map.maxViewWithKey map))
    put $ Map.insert newKey item map
    return newKey

